#ifndef	__SOCK_SET_H__
#define __SOCK_SET_H__

#ifndef	MAXSOCKET
#define MAXSOCKET 256
#endif

#ifndef MAXDATALEN
#define MAXDATALEN 2048
#endif

#ifndef SOCKSETMARK1
#define SOCKSETMARK1 0x55
#endif

#ifndef SOCKSETMARK2
#define SOCKSETMARK2 0xaa
#endif

#ifndef POLLTIMEOUT
#define POLLTIMEOUT 5
#endif

#ifndef MAXTIMEOUT
#define MAXTIMEOUT 1
#endif

#ifndef TRACE

#ifdef  _DEBUG

#include    <stdio.h>
#include    <stdlib.h>
#define TRACE printf

#else

#define TRACE

#endif

#endif

#ifdef	_WIN32
#include	"windows.h"
#pragma comment(lib,"sockset.lib")
#endif

#include	"sys/types.h"
#include	"string.h"
#include 	<sys/types.h>
#include 	<fcntl.h>
#include	"stdio.h"
#include	"stdlib.h"

#ifdef	_WIN32
#include	"winsock.h"
#include	"process.h"
#endif

#ifndef	_WIN32
#include	<sys/socket.h>
#include	<sys/types.h>
#include	<netinet/in.h>
#include	<pthread.h>
#endif

#ifdef DLL_EXPORT
#undef DLL_EXPORT
#endif

#ifdef SOCKSET_EXPORTS
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif

typedef struct tagSockFormat
{
unsigned char	nMark1;//0x55aa
unsigned char	nMark2;
unsigned short   nSize;// read or write size
unsigned char   nFlag;
unsigned char	nNoUse1;
unsigned short	nNoUse2;
char    pData[MAXDATALEN];
}SSockFormat;


class CServerSocket;
class CSocketData;

typedef  unsigned int (*READ_CALLBACK_FUNC)(CSocketData *pSocket,char * pReadData,
    unsigned  int nReadData);

	
class DLL_EXPORT CSocketBase
{
public:
	CSocketBase();
	~CSocketBase();
//	virtual ~CSocketBase();
	static  unsigned int 	Create(unsigned long nType=1);
	static unsigned long Close( unsigned int nSocket);
	static int 	Connect(const char * pServer,unsigned long nPort);
	static unsigned long ShutDown(unsigned  int nSocket);
	static unsigned long	Read(unsigned  int nSocket,void * pBuffer,unsigned long nLen,
					unsigned long nWaitFlag=1);
	static unsigned long	TryRead( unsigned int nSocket,void * pBuffer,unsigned long nLen,
					unsigned long nWaitFlag=1);
	static unsigned long	Write( unsigned int nSocket,void  * pBuffer,unsigned long nLen,
					unsigned long nWaitFlag=1);
	static unsigned long	Check( unsigned int nSocket);
	static unsigned long CheckRead( unsigned int nSocket, unsigned int nTimeout);
	static unsigned long CheckWrite( unsigned int nSocket, unsigned int nTimeout);
	static unsigned long CheckReadWrite( unsigned int nSocket, unsigned int nTimeout);
};

class DLL_EXPORT CSocketData
{
public:
//	unsigned long m_nSyncFlag;
	unsigned long Check();
	 unsigned int m_nSocket;
    CSocketData();
	~CSocketData();
//  virtual ~CSocketData();
	unsigned long	SetSocket( unsigned int nSocket);
    virtual unsigned long    Close();
    long    Read(void * pBuffer,unsigned long nLen,
				unsigned long nWaitFlag=1);
    long    Write(void  * pBuffer,unsigned long nLen,
				unsigned long nWaitFlag=1);
	 unsigned int		m_nServerPort;
	char	m_pServerName[256];
	char	m_pClientName[256];
	 unsigned int		GetSocketNumber();
	 unsigned int		GetServerPort();
	char * 	GetServerName();
	char * 	GetClientName();
private:
    void ClearRequest();
    unsigned long CheckRequest(SSockFormat * pSockFormat);

};

typedef	struct tagSReadProcParam
{
	 unsigned int nSocket;
	 unsigned int nMaxDataLen;
	CServerSocket * pServer;
	 unsigned int nIndex;
	char pClientName[256];
	char * pBuffer;
} SReadProcParam;

	
class DLL_EXPORT CClientSocket:public CSocketData
{
public:
	virtual unsigned long  Close();
	CClientSocket();
	~CClientSocket();
//	virtual ~CClientSocket();
	unsigned long	Connect(const char * pServer,unsigned long nPort);
	CServerSocket * m_pServer;
	unsigned long m_nIndex;
};

class DLL_EXPORT CServerSocket:public CSocketData
{
public:
	unsigned long	m_nType;
	sockaddr_in m_inAddr;
	CServerSocket();
	~CServerSocket();
//	virtual ~CServerSocket();
	unsigned long	Bind(unsigned long nPort,unsigned long nWaitFlag=0);
	unsigned long	SetReadCallback(READ_CALLBACK_FUNC pCallback,
				 unsigned int nMaxDataLen=0x4000,int nRawFlag=0);
	 unsigned int		Accept();
	virtual unsigned long Close();
	void	Lock();
	void	Lock0();
	void 	Unlock();
	void 	Unlock0();
public:
	unsigned int		m_pSocketList[MAXSOCKET];
	unsigned long	m_nSocketList;
	int		m_nRawFlag;

#ifdef	_WIN32	
	HANDLE m_pThreadList[MAXSOCKET];
	HANDLE m_nCallbackThread;
	HANDLE m_nTimeoutThread;
	HANDLE m_nAcceptThread;
	CRITICAL_SECTION m_Mutex;
#else
	pthread_t m_pThreadList[MAXSOCKET];
	pthread_t m_nCallbackThread;
	pthread_t m_nTimeoutThread;
	pthread_t m_nAcceptThread;
	pthread_mutex_t m_Mutex;
#endif

	unsigned int		m_nMaxDataLen;
	READ_CALLBACK_FUNC  m_pReadCallback;
   	unsigned int     GetFreeIndex();
	unsigned long	m_nCloseFlag;

};
	
typedef	struct tagSockset
{
	unsigned long nType;
//	unsigned long nSocket;
	char pServer[256];
	unsigned long nPort;
	unsigned long nUse;
	CClientSocket *pSocket;
}	SSockset;

	
class DLL_EXPORT CSocketSet
{
public:
	CSocketSet();
	~CSocketSet();
//	virtual ~CSocketSet();
	 unsigned int 	AddServer(const char * pServer,unsigned long nPort);
	 unsigned int 	AddServer(const char * pSocketName);
	unsigned long 	Connect();
	unsigned long 	Disconnect();
	unsigned long	RemoveAll();
	 unsigned int 	RemoveServer( unsigned int nIndex);
	 unsigned int 	RemoveServer(const char * pServer,unsigned long nPort);
	 unsigned int		RemoveServer(const char * pSocketName);
    unsigned long    Read( unsigned int nIndex,void * pBuffer,unsigned long nLen,
                unsigned long nWaitFlag=1);
    unsigned long    Write( unsigned int nIndex,void  * pBuffer,unsigned long nLen,
                unsigned long nWaitFlag=1);
	unsigned long	Close();
	unsigned long	DisconnectServer( unsigned int nIndex);
	void	Lock();
	void	Unlock();
public:
	SSockset m_pSocksetList[MAXSOCKET];
	unsigned long	m_nSocksetList;
	 unsigned int		m_nCurRead;
	 unsigned int		m_nCurWrite;

#ifdef	_WIN32
    CRITICAL_SECTION m_Mutex;
	HANDLE	m_nTimeoutThread;
#else
    pthread_mutex_t m_Mutex;
	pthread_t	m_nTimeoutThread;
#endif

	unsigned long	m_nConnectFlag;
	unsigned long	m_nConnectTotal;

private:
	 unsigned int 	iGetFreeIndex();
	 unsigned int		iGetServerIndex(const char * pServer,unsigned long nPort);
	 unsigned int		iGetServerIndex(const char * pSocketName);
};

#endif

